home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / tex-k / fontname-1.6.tar.gz / fontname-1.6.tar / fontname-1.6 / fnget.c < prev    next >
C/C++ Source or Header  |  1993-05-20  |  11KB  |  345 lines

  1. /*
  2. FONTNAME.C
  3. Graham Asher, 10th December 1992
  4.  
  5. Converts fonts named according to Karl Berry's scheme into full names.
  6.  
  7. The scheme for using the eight letters of a filename is:
  8.  
  9. STTWVEDD
  10.  
  11. where S = source (foundry), TT = typeface name, W = weight, V = variant,
  12. E = width/expansion and DD = design size. DD is omitted if the font is
  13. scaled, E is omitted if normal, and V is omitted if it and E are normal.
  14.  
  15. At present only one variant code is read but future versions may allow
  16. for more than one variant.
  17. */
  18.  
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <ctype.h>
  22. #include <string.h>
  23.  
  24. /* Table of 36 (0-9, a-z) sources and foundries. */
  25. static char *S[36] =
  26. {
  27. "unknown source ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  28. "Autologic ", "Bitstream ", "Compugraphic ", NULL, NULL, "public domain ",
  29. "Free Software Foundation (GNU) ", "Bigelow & Holmes ",
  30. "International Typeface Corporation ", NULL, NULL, NULL, "Monotype ", "IBM ",
  31. NULL, "Adobe ", NULL, "raw ", "Sun ", NULL, "URW ", NULL, NULL,
  32. "American Mathematical Society ", NULL, "bizarre "
  33. };
  34.  
  35. /*
  36. Table of typeface codes and names, sorted on the two-letter code and
  37. terminated by a NULL.
  38. */
  39. static char *TT[] =
  40. {
  41. "aaAachen ", "abArnold Boecklin ", "acAdobe Caslon ", "adAdobe Garamond ",
  42. "agAvant Garde ", "alAlbertus ", "amAmericana ", "aoAntique Olive ",
  43. "arArcadia ", "asAldus ", "atAmerican Typewriter ", "auAuriol ", "avAvenir ",
  44. "azAkzidenz Grotesque ", "b0Blackoak ", "bbBembo ", "bcBanco ", "bdBodoni ",
  45. "bgBenguiat ", "bhBauhaus ", "biBirch ", "bkBookman ", "blBelwe ", "boBalloon ",
  46. "bpBundesbahn Pi ", "brBerling ", "bsBakerSignet ", "buBrush ", "bvBaskerville ",
  47. "bwBroadway ", "byBerkeley ", "c0Carolina ", "c2Caslon 224 ", "c3Caslon 3 ",
  48. "c5Caslon 540 ", "caCaslon ", "cbCooper Black ", "ccCascade ", "cdClarendon ",
  49. "ceCentennial ", "cfClearface ", "cgCharlemagne ", "chCharter ", "ciCandida ",
  50. "clCloister ", "cmComputer Modern ", "cnCentury ", "coCochin ", "cpCopperplate ",
  51. "cqCheq ", "crCourier ", "csCentury Schoolbook ", "ctCheltenham ",
  52. "cuCentury Old Style ", "cvClairvaux ", "cwCottonwood ", "cxCaxton ", "cyCity ",
  53. "dcDom Casual ", "ddDuc de Berry ", "drDoric ", "efEgyptienneF ",
  54. "egStempel Garamond ", "ehEngschrift ", "epEuropean Pi ", "erEras ",
  55. "esEurostile ", "euEuler ", "exExcelsior ", "faFormata ", "fgFranklin Gothic ",
  56. "fnFenice ", "foFolio ", "fqFriz Quadrata ", "frFrutiger ", "ftFette Fraktur ",
  57. "fuFutura ", "fyFlyer ", "g1Gothic Thirteen ", "g3Garamond No. 3 ",
  58. "gbGothic BBB ", "ggGarth Graphic ", "gjGranjon ", "glGalliard ", "gmGaramond ",
  59. "goGoudy Old Style ", "gpGlypha ", "gsGill Sans ", "gtGoudy Text ", "guGuardi ",
  60. "gvGiovanni ", "gyGoudy ", "hbHobo ", "hcHerculanum ", "hgHiroshige ",
  61. "hiHelvetica Inserat ", "hmCharme ", "hnHelvetica Neue ", "hrHelvetica Rounded ",
  62. "hvHelvetica ", "iaInsignia ", "icImpact ", "igSimoncini Garamond ",
  63. "ilCaecilia ", "imImago ", "inIndustria ", "ipImpressum ", "itItalia ",
  64. "iwIronwood ", "jnJanson ", "joJoanna ", "jpJuniper ", "kbKabel ", "krKorinna ",
  65. "ksKuenstler Script ", "kuKaufmann ", "lbLubalin Graph ", "lcLucida ", "lfLife ",
  66. "lgLetter Gothic ", "lnLino ", "loLithos ", "lsMittelschrift ", "ltLutetia ",
  67. "lwLeawood ", "mdMeridien ", "mhMachine ", "miMedici ", "mlMelior ", "mnMinion ",
  68. "mpMemphis ", "mqMesquite ", "mrMadrone ", "msMistral ", "mtMinister ", "mvMalvern ",
  69. "mxMaximus ", "naNew Aster ", "nbNew Baskerville ", "ncNew Century Schoolbook ",
  70. "ndNew Caledonia ", "nfNofret ", "ngNews Gothic ", "ntTimes New Roman ",
  71. "nuNuptial ", "nvNovarese ", "nzNeuzeit S ", "o7Old Style 7 ", "oaOCR-A ",
  72. "obOCR-B ", "ocConcorde ", "omOmnia ", "onCorona ", "opOptima ", "orOrator ",
  73. "otCoronet ", "oyOlympian ", "p0Poplar ", "paPark Avenue ", "pePrestige Elite ",
  74. "pgPeignot ", "piPlantin ", "plPalatino ", "poPonderosa ", "ppPerpetua ",
  75. "pqPost Antiqua ", "psParisian ", "ptPresent ", "pxPoppl Pontifex ", "qrQuorum ",
  76. "raRaleigh ", "roRotis ", "rpReporter ", "rqRussell Square ", "rtCarta ",
  77. "rvRevue ", "rwRockwell ", "ryRyumin ", "s0San Marco ", "sbSabon ", "scSlimbach ",
  78. "sfSerifa ", "sgSerif Gothic ", "shShannon ", "slStencil ", "snSpartan ",
  79. "soSonata ", "spSerpentine ", "srSnell Roundhand ", "ssStempel Schneidler ",
  80. "stStone ", "svSouvenir ", "sxSyntax ", "sySymbol ", "tbBerthold Bodoni ",
  81. "teTimes Europa ", "tfTiffany ", "tgTrade Gothic ", "tiTech Phonetic ",
  82. "tjTrajan ", "tkTektok ", "tlCastellar ", "tmTimes ", "tpTempo ",
  83. "tvTrump Mediaeval ", "ubBauer Bodoni ", "ugBenguiat Gothic ", "uhCushing ",
  84. "ulUniversal ", "umUmbra ", "unUnivers ", "urCentaur ", "utUtopia ", "uwUsherwood ",
  85. "uyUniversity ", "vcVectora ", "vjVeljovic ", "vlVersailles ", "vrVAG Rounded ",
  86. "wbWalbaum ", "wdWeidemann ", "wgWilhelmKlingsporGotisch ", "wkWilke ",
  87. "woWood ", "wsWeiss ", "wwWillow ", "ymStymie ", "zcZapf Chancery ",
  88. "zdZapf Dingbats ", "zgNeuzeit Grotesk ", NULL
  89. };
  90.  
  91. /* Table of 26 weights. */
  92. static char *W[26] =
  93. {
  94. "thin ", "bold ", "black ", "demi bold ", NULL, NULL, NULL, "heavy ",
  95. "extra light ", NULL, "book ", "light ", "medium ", NULL, NULL, "poster ",
  96. NULL, "normal weight ", "semi bold ", NULL, "ultra ", NULL, NULL, "extra bold ",
  97. NULL, NULL
  98. };
  99.  
  100. /* Table of 36 variants. */
  101. static char *V[36] =
  102. {
  103. "Adobe standard encoding ", "semi sans ", "changed characters only ",
  104. "fractions ", NULL, NULL, NULL, NULL, NULL, "oldstyle digits ",
  105. "Adobe alternate encoding ", "bright ", "small caps ", "display ", "engraved ",
  106. "Fraktur ", "grooved ", "shadow ", "italic ", "invisible ", "Greek ",
  107. "outline ", "math italic ", "informal ", "oblique ", "ornament ",
  108. "GNU text complement encoding ", "normal variant ", "sans serif ", "typewriter ",
  109. "unslanted italic ", "math extension ", "script ", "Adobe expert encoding ",
  110. "symbol ", "Cyrillic "
  111. };
  112.  
  113. /* Table of 26 widths (expansions). */
  114. static char *E[26] =
  115. {
  116. NULL, NULL, "condensed ", NULL, "expanded ", NULL, NULL, NULL, NULL, NULL, NULL,
  117. NULL, NULL, "narrow ", "extra condensed ", "compressed ", "extra compressed ",
  118. "normal width ", NULL, "thin ", "ultra compressed ", NULL, "wide ", "extended ",
  119. NULL, NULL
  120. };
  121.  
  122. static void normalise(char *s);
  123. static void index26(char *p);
  124. static void index36(char *p);
  125. static int compare_TTs(const char **j,const char **k);
  126.  
  127. /*
  128. A main() for testing.
  129. */
  130. #ifdef TESTING
  131. int
  132. main(int argc,char **argv)
  133. {
  134. int i;
  135. char buffer[80];
  136.  
  137. if (argc < 3)
  138.   {
  139.   puts("usage: fontname <template> <filename(s)>");
  140.   exit(1);
  141.   }
  142.  
  143. for (i = 2; i < argc; i++)
  144.   {
  145.   FNget(buffer,sizeof(buffer),argv[i],argv[1]);
  146.   printf("%s = %s\n",argv[i],buffer);
  147.   }
  148. return (0);
  149. }
  150. #endif
  151.  
  152. /*
  153. Convert a filename to a font name. The template, an eight-character string
  154. in the form STTWVEDD, instructs FNget() which parts to include and which to
  155. omit: '-' means omit, '*' means include, and any other letter means `include
  156. if not equal to this letter'. The default template is "***rrr**". If the
  157. template is null or shorter than eight characters the missing parts are
  158. taken to be the defaults. For example, to omit the foundry unless
  159. non-Adobe, and always omit the variant, use the template "p***-"; and
  160. to omit source unless non-public domain, and the typeface unless
  161. non-Computer Modern, use "fcm". (BUT for now any names starting `cm..',
  162. `eu..' or `ms..' (Computer Modern, Euler and American Mathematical Society)
  163. are left untranslated.) The decoded name is placed in <dest> as a
  164. null-terminated string of <size> characters or less including the null.
  165. If decoding is successful 1 is returned, otherwise 0 is returned and the
  166. filename is simply copied into <dest>.
  167. */
  168. int
  169. FNget(char *dest,size_t size,char *filename,char *template)
  170. {
  171. char t[9], f[9], name[2];
  172. int i, dpos;
  173. char *s = "", *tt = "", *w = "", *v = "", *e = "", *dd = "", *key = name;
  174. char **b;
  175. static int TT_count;
  176.  
  177. /* Extend the template and filename to 8 characters and force to lowercase. */
  178. strcpy(t,"***rrr**");
  179. if (template)
  180.   for (i = 0; i < 8 && template[i]; i++)
  181.     t[i] = tolower(template[i]);
  182. strcpy(f,"   rrr  ");
  183. if (filename)
  184.   for (i = 0; i < 8 && isalnum(filename[i]); i++)
  185.     f[i] = tolower(filename[i]);
  186.  
  187. /*
  188. Reject Computer Modern, Euler and American Mathematical Society fonts:
  189. we want to be able to use these without translating them or changing their
  190. names.
  191. */
  192. if (!strncmp(f,"cm",2) || !strncmp(f,"eu",2) || !strncmp(f,"ms",2))
  193.   {
  194.   strncpy(dest,filename,size);
  195.   return (0);
  196.   }
  197.  
  198. /*
  199. Find the position of the design size. This method means that variant codes
  200. which are digits only work if an expansion code follows.
  201. */
  202. if (isdigit(f[4]) && (!filename[5] || isdigit(f[5])))
  203.   dpos = 4;
  204. else if (isdigit(f[5]))
  205.   dpos = 5;
  206. else if (isdigit(f[6]))
  207.   dpos = 6;
  208. else
  209.   dpos = 8;
  210.  
  211. /* Normalise the template and filename. */
  212. normalise(t);
  213. normalise(f);
  214.  
  215. /* Restore design size if obliterated by normalisation. */
  216. if (dpos < 6)
  217.   strcpy(&f[dpos],&filename[dpos]);
  218.  
  219. /* Get source. */
  220. if (f[0] > 35)
  221.   s = NULL;
  222. else if (t[0] != '-' && t[0] != f[0])
  223.   s = S[f[0]];
  224.  
  225. /* Get typeface name. */
  226. if (t[1] != '-' && (t[1] != f[1] || t[2] != f[2]))
  227.   {
  228.   while (TT[TT_count])
  229.     TT_count++;
  230.   name[0] = f[1];
  231.   name[1] = f[2];
  232.   b = (char **)bsearch(&key,TT,TT_count,sizeof(TT[0]),compare_TTs);
  233.   tt = b ? (*b) + 2 : NULL;
  234.   }
  235.  
  236. /* Get weight. */
  237. if (f[3] > 25)
  238.   w = NULL;
  239. else if (t[3] != '-' && t[3] != f[3])
  240.   w = W[f[3]];
  241.  
  242. /* Get variant. */
  243. if (dpos > 4)
  244.   {
  245.   if (f[4] > 35)
  246.     v = NULL;
  247.   else if (t[4] != '-' && t[4] != f[4])
  248.     v = V[f[4]];
  249.   }
  250.  
  251. /* Get expansion. */
  252. if (dpos > 5)
  253.   {
  254.   if (f[5] > 25)
  255.     e = NULL;
  256.   else if (t[5] != '-' && t[5] != f[5])
  257.     e = E[f[5]];
  258.   }
  259.  
  260. /* Get design size. */
  261. if (t[6] != '-' && dpos < 8 && strcmp(&t[6],&f[dpos]))
  262.   dd = &f[dpos];
  263.  
  264. /* If there are any errors return the filename untranslated. */
  265. if (!s || !tt || !w || !v || !e || !dd)
  266.   {
  267.   strncpy(dest,filename,size);
  268.   return (0);
  269.   }
  270.  
  271. /* Construct the full name in the destination buffer. */
  272. i = 0;
  273. size--;
  274. while (*s && i < size)
  275.   *dest++ = *s++, i++;
  276. while (*tt && i < size)
  277.   *dest++ = *tt++, i++;
  278. while (*w && i < size)
  279.   *dest++ = *w++, i++;
  280. while (*v && i < size)
  281.   *dest++ = *v++, i++;
  282. while (*e && i < size)
  283.   *dest++ = *e++, i++;
  284. if (*dd)
  285.   {
  286.   while (*dd && *dd != ' ' && i < size)
  287.     *dest++ = *dd++, i++;
  288.   if (i < size - 1)
  289.     strcpy(dest,"pt"), dest += 2, i += 2;
  290.   }
  291. if (dest[-1] == ' ')
  292.   dest--;
  293. *dest = 0;
  294. return (1);
  295. }
  296.  
  297. /* Normalise a filename or template. */
  298. static void
  299. normalise(char *s)
  300. {
  301. index36(&s[0]);
  302. index26(&s[3]);
  303. index36(&s[4]);
  304. index26(&s[5]);
  305. }
  306.  
  307. /*
  308. Set a character to the range 0..25 if it is a letter,
  309. or to '*' unless it is '-';
  310. */
  311. static void
  312. index26(char *p)
  313. {
  314. if (islower(*p))
  315.   *p -= 'a';
  316. else if (*p != '-')
  317.   *p = '*';
  318. }
  319.  
  320. /*
  321. Set a character to the range 0..9 if it is a digit, 10..35 if it is a letter,
  322. or to '*' unless it is '-';
  323. */
  324. static void
  325. index36(char *p)
  326. {
  327. if (isdigit(*p))
  328.   *p -= '0';
  329. else if (islower(*p))
  330.   *p -= ('a' - 10);
  331. else if (*p != '-')
  332.   *p = '*';
  333. }
  334.  
  335. /*
  336. Compare two two-letter typeface codes.
  337. */
  338. static int
  339. compare_TTs(const char **j,const char **k)
  340. {
  341. const char *x = *j, *y = *k;
  342.  
  343. return (strncmp(x,y,2));
  344. }
  345.